上篇提到如何為 component 添加樣式,文末得到了一個使用 bootstrap 樣式的表單,
接下來談談 react 中的表單
input / textarea / checkbox / select
react 用 value 這個 attribute 來控制表單內 element 的顯示值
因為 for 詞在 react 是保留字(reversed word),所以 label 中要寫為 htmlfor
<label htmlFor='inputVal'>對 input 輸入
<input type="text" />
</label>
一樣將 state 連上 value
onChange
<textarea
name='textVal'
onChange={this.handleChange}
value={this.state.textVal}
/>
<input
name='inputVal'
onChange={this.handleChange}
value={this.state.inputVal}
/>
checked 取得預設選取值
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
value 取得 select 值
<select
value={this.state.value}
onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
對 select 的 value 傳入陣列作為 value
<select multiple={true} value={['B', 'C']}>...
對 element 增加 name 這個 attribute,動態產生 setState state 中的 key
用 []
裝取動態產生的 evt.target.name
constructor(props){
...
this.handleChange = this.handleChange.bind(this); // 綁定 method 到 class 實體
this.state = {name:'',qty:''}; // 初始化 state
}
...
// 把 evt 接進來
handleChange(evt){
this.setState({[evt.target.name]:evt.target.value});
// 動態產生將 state 中匹配 name 的項目更新
}
...
render(){
return(
<input
id='qty' //接 label 用
name='qty' //接 handleChange method 用
vaule={this.state.qty} // vaule 即是在 state 中名為 'qty' 項目的值
onChange={this.handleChange} // onChange 接 method
/>
)
}
所謂的 Controlled component 就是用 state 作為唯一資料來源的 component
當 state 被 update,其上的 value 也隨之改變
每一次對 input 鍵入值(onChange) 觸發 updateHandler method,該 method set state 為新值
該 component 的 value 因 state 改變 也隨之被變更
class Form extends React.Component{
constructor(){
...
this.updateHandler = this.updateHandler.bind(this);
}
updateHandler(){...}
render(){
return(
<input
type="text"
name="customId"
id="customId"
value={this.state.customId}
onChange={this.updateHandler}
/>
)
}
}
多數情況下 react 中,表單中使用的多半是 controlled components
uncontrolled components 就是 value 跟 state 狀態不一致的 component
為了阻止預設 submit 表單造成重新渲染 component
所以傳入事件(e) .preventDefault 阻止 submit
handleSubmit(e){
e.preventDefault();
// ...
}